#include "mygraphicsview.h"
#include <QDebug>
#include <QMouseEvent>
#include <QWheelEvent>
#include "dwgpointitem.h"
#include "dwglineitem.h"
#include "dwgcircleitem.h"
#include "dwgrectitem.h"
#include "dwgellipseitem.h"
#include <QtMath>

MyGraphicsView::MyGraphicsView(QWidget *parrent)
    : QGraphicsView(parrent)
{
    setMouseTracking(true); // 设置不按键时的鼠标移动响应
    this->setAlignment(Qt::AlignLeft|Qt::AlignBottom); // 设置左下对齐方式
    this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // 关闭横滚动条
    this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // 关闭竖滚动条
    setTransformationAnchor(QGraphicsView::AnchorUnderMouse); // 设置以鼠标点为锚点
    this->scale(1,-1); // 翻转 Y 轴正向方向

    this->setRenderHint(QPainter::Antialiasing,true); // 为 View 视图设置反走样渲染模式，会影响效率
    this->setViewportUpdateMode(QGraphicsView::FullViewportUpdate); // 为提高刷新效率指定全视图刷新模式，更高的绘制开销
}

DwgLineItem *tempLine = new DwgLineItem; // 试做直线绘制效果预览（橡皮线）功能
DwgCircleItem *tempCircle = new DwgCircleItem;
DwgRectItem *tempRect = new DwgRectItem;
DwgEllipseItem *tempEllipse = new DwgEllipseItem;
void MyGraphicsView::mouseMoveEvent(QMouseEvent *event)
{
    if(event->buttons() == Qt::MiddleButton)
    {
        qreal dx = temppt.x()-this->mapToScene(event->pos()).x(); // 计算鼠标当前点与起始点之间的水平距离 dx
        qreal dy = temppt.y()-this->mapToScene(event->pos()).y(); // 计算鼠标当前点与起始点之间的竖直距离 dy
        QTransform trans = this->transform(); // 创建一个变换矩阵，获得当前视图的矩阵值
        trans.translate(dx,dy); // 对变换矩阵做平移变换
        this->setTransform(trans); // 把变换之后的矩阵赋值给 View
    }

    if (!isFirst) {
        if(mCurDrawType == DLine){
            // 实时更新临时线终点
            tempLine->mLineWidth = myCurLineWidth;
            tempLine->mPenStyle = Qt::DashLine;
            tempLine->mColor = Qt::blue;
            tempLine->mStartPt = temppt;
            tempLine->mEndPt = mapToScene(event->pos());
            this->scene()->addItem(tempLine);
        }
        if(mCurDrawType == DCircle){
            tempCircle->mLineWidth = myCurLineWidth;
            tempCircle->mPenStyle = Qt::DashLine;
            tempCircle->mColor = Qt::blue;
            tempCircle->mCenPt = temppt;
            tempCircle->mRad = sqrt(pow(mapToScene(event->pos()).x()-temppt.x(),2)+pow(mapToScene(event->pos()).y()-temppt.y(),2));
            this->scene()->addItem(tempCircle);
        }
        if(mCurDrawType == DRectangle){
            tempRect->mLineWidth = myCurLineWidth;
            tempRect->mPenStyle = Qt::DashLine;
            tempRect->mColor = Qt::blue;
            tempRect->mLTPt = temppt;
            tempRect->mRBPt = mapToScene(event->pos());
            this->scene()->addItem(tempRect);
        }
        if(mCurDrawType == DEllipse && !isSecond){
            tempEllipse->mLineWidth = myCurLineWidth;
            tempEllipse->mPenStyle = Qt::DashLine;
            tempEllipse->mColor = Qt::blue;
            tempEllipse->mCenPt = temppt;
            tempEllipse->mRadA = sqrt(pow(temppt2.x()-temppt.x(),2)+pow(temppt2.y()-temppt.y(),2));
            tempEllipse->mRadB = sqrt(pow(mapToScene(event->pos()).x()-temppt.x(),2)+pow(mapToScene(event->pos()).y()-temppt.y(),2));
            this->scene()->addItem(tempEllipse);
        }
        scene()->update();  // 触发重绘
    }

    //qDebug() <<" View pos mapToScene :" <<mapToScene(event->pos()); // 输出鼠标移动位置映射到场景的坐标值
    QGraphicsView::mouseMoveEvent(event); // 把本事件传递给下一个接收者
}

void MyGraphicsView::mousePressEvent(QMouseEvent *event)
{
    if(event->buttons() == Qt::LeftButton)
    {
        if(mCurDrawType == DPoint)
        {
            DwgPointItem *pt = new DwgPointItem;
            QPointF pospt= mapToScene(event->pos());
            pt->setPos(pospt);				// 设置点的位置
            pt->mColor = myCurColor;
            this->scene()->addItem(pt);
        }
        if(mCurDrawType == DLine)
        {
            if(isFirst)
            {
                this->setCursor(Qt::CrossCursor);
                temppt = mapToScene(event->pos());
                //                qDebug() << "1 pt" << temppt;
                isFirst = false;
            }
            else
            {
                QPointF endpt = mapToScene(event->pos());
                //                qDebug() << "2 pt" << endpt;
                //                this->scene()->addLine(temppt.x(),temppt.y(),endpt.x(),endpt.y());
                DwgLineItem *line =new DwgLineItem;
                line->mStartPt = temppt;
                line->mEndPt = endpt;
                line->mLineWidth = myCurLineWidth;
                line->mPenStyle = myCurPenStyle;
                line->mColor = myCurColor;
                this->scene()->addItem(line);
                isFirst = true;

                if (tempLine) {
                    scene()->removeItem(tempLine);
                    // delete tempLine;
                    // tempLine = nullptr;
                }
            }
        }
        if(mCurDrawType == DPolyLine)
        {
            if(isFirst)
            {
                this->setCursor(Qt::CrossCursor);
                temppt = mapToScene(event->pos());
                isFirst = false;
            }
            else
            {
                QPointF endpt = mapToScene(event->pos());
                DwgLineItem *line =new DwgLineItem;
                line->mStartPt = temppt;
                line->mEndPt = endpt;
                temppt = endpt; // 保存endpt继续绘制下一直线，并且isFirst = false不变
                line->mLineWidth = myCurLineWidth;
                line->mPenStyle = myCurPenStyle;
                line->mColor = myCurColor;
                this->scene()->addItem(line);
            }
        }
        if(mCurDrawType == DCircle)
        {
            if(isFirst)
            {
                this->setCursor(Qt::CrossCursor);
                temppt = mapToScene(event->pos());
                isFirst = false;
            }
            else
            {
                DwgCircleItem *circle = new DwgCircleItem(temppt,mapToScene(event->pos()));
                circle->mLineWidth = myCurLineWidth;
                circle->mPenStyle = myCurPenStyle;
                circle->mColor = myCurColor;
                this->scene()->addItem(circle);
                isFirst = true;

                if (tempCircle) {
                    scene()->removeItem(tempCircle);
                }
            }
        }
        if(mCurDrawType == DEllipse)
        {
            if(isFirst)
            {
                this->setCursor(Qt::CrossCursor);
                temppt = mapToScene(event->pos());
                isFirst = false;
            }
            else if(isSecond)
            {
                this->setCursor(Qt::CrossCursor);
                temppt2 = mapToScene(event->pos());
                isSecond = false;
            }
            else
            {
                DwgEllipseItem *ellipse = new DwgEllipseItem(temppt,temppt2,mapToScene(event->pos()));
                ellipse->mLineWidth = myCurLineWidth;
                ellipse->mPenStyle = myCurPenStyle;
                ellipse->mColor = myCurColor;
                this->scene()->addItem(ellipse);
                isFirst = true;
                isSecond = true;

                if (tempCircle) {
                    scene()->removeItem(tempCircle);
                }
            }
        }
        if(mCurDrawType == DRectangle)
        {
            if(isFirst)
            {
                this->setCursor(Qt::CrossCursor);
                temppt = mapToScene(event->pos());
                isFirst = false;
            }
            else
            {
                DwgRectItem *rect = new DwgRectItem(temppt,mapToScene(event->pos()));
                rect->mLineWidth = myCurLineWidth;
                rect->mPenStyle = myCurPenStyle;
                rect->mColor = myCurColor;
                this->scene()->addItem(rect);
                isFirst = true;

                if (tempRect) {
                    scene()->removeItem(tempRect);
                }
            }
        }
    }

    if(event->buttons() == Qt::MiddleButton)        // 判断鼠标中键是否按下
    {
        this->setCursor(Qt::SizeAllCursor);         // 改变光标形状为移动光标
        temppt = mapToScene(event->pos());          // 记录下鼠标移动的起始点
    }
    QGraphicsView::mousePressEvent(event); // 把鼠标起始事件传递给下一个接收者
}

void MyGraphicsView::mouseReleaseEvent(QMouseEvent *event)
{
    if(event->buttons() == Qt::MiddleButton)
        this->setCursor(Qt::ArrowCursor);
}


void MyGraphicsView::wheelEvent(QWheelEvent *event)
{
    qreal curScale;
    if(event->angleDelta().y() >0)  // 设置一个缩放比例，分别为1.1或0.9
        curScale = 1.1;
    else
        curScale = 0.9;

    m_trans = this->transform();        // 获得当前视图的变换矩阵
    m_trans.scale(curScale,curScale);   // 根据缩放比例附加到变换矩阵上
    setTransform(m_trans);              // 把变换矩阵应用到视图上
    update();

    QGraphicsView::wheelEvent(event);   // 把鼠标滚轮事件传递给下一个接收者
}
